package com.qf.service;

import com.qf.config.IdWorker;
import com.qf.constant.CacheConstants;
import com.qf.constant.RabbitMQConstants;
import com.qf.constant.ReportStateConstants;
import com.qf.constant.SourceType;
import com.qf.feign.CacheFeign;
import com.qf.model.StandardSubmit;
import com.qf.pojo.SmsInterfaceForm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class SmsInterfaceServiceImpl implements SmsInterfaceService{

    @Autowired
    private CacheFeign cacheFeign;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public Map<String, String> checkSmsForm(SmsInterfaceForm smsForm) {

        Map<String, String> resultMap = new HashMap<>();

        //1.根据clientId到缓存中获取客户对象
        Map<String, String> clientMap = cacheFeign.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + smsForm.getClientID());

        //2.如果根据客户端id获取不到客户对象说明clientId错误
        if(clientMap == null || clientMap.size() == 0){

            resultMap.put("code", "101");
            resultMap.put("msg", "认证错：clientId错误");
            log.info("[接口模块 - SmsServiceImpl类],短信对象深度校验错误,clientid错误,smsForm={}", smsForm);
            return resultMap;
        }

        //3.校验客户的密码是否正确
        String pwd = clientMap.get("pwd");
        if(!smsForm.getPwd().equals(pwd)){
            resultMap.put("code", "102");
            resultMap.put("msg", "密码错误");
            log.info("[接口模块 - SmsServiceImpl类],短信对象深度校验错误,密码错误,smsForm={}", smsForm);
            return resultMap;
        }

        //4.校验短信内容是否在500个字符以内
        String content = smsForm.getContent();
        if(content.length() > 500){
            resultMap.put("code", "104");
            resultMap.put("msg", "消息长度错，为空或超长（目前定为500个字）");
            log.info("[接口模块 - SmsServiceImpl类],短信对象深度校验错误,短信内容过长,smsForm={}", smsForm);
            return resultMap;
        }

        //5.校验客户发送的目标手机号是否符合规则
        String[] mobileArray = smsForm.getMobile().split(",");
        String regex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
        //错误的号码集合
        Set<String> errorMobile = new HashSet<>();
        for (String mobile : mobileArray) {
            if(!mobile.matches(regex)){
                errorMobile.add(mobile);
            }
        }

        //判断是否有错误的号码，如果有进行提示
        if(errorMobile.size() > 0){
            resultMap.put("code", "105");
            resultMap.put("msg", "手机号错误");
            log.info("[接口模块 - SmsServiceImpl类],短信对象深度校验错误,发送短信目标号码错误,错误的号码为={}", errorMobile);
            return resultMap;
        }

        //6.校验客户ip地址是否正确
        String ipaddress = clientMap.get("ipaddress");
        if(!smsForm.getIp().equals(ipaddress)){
            resultMap.put("code", "103");
            resultMap.put("msg", "IP校验错误");
            log.info("[接口模块 - SmsServiceImpl类],短信对象深度校验错误,客户服务器ip错误,smsForm={}", smsForm);
            return resultMap;
        }

        //7.校验下行编码是否正确
        try {
            long srcID = Long.parseLong(smsForm.getSrcID());
        } catch (NumberFormatException e) {
            e.printStackTrace();
            resultMap.put("code", "106");
            resultMap.put("msg", "下行编号（srcID）错误");
            log.info("[接口模块 - SmsServiceImpl类],短信对象深度校验错误,下行编码错误,smsForm={}", smsForm);
            return resultMap;
        }

        //8.如果以上校验都正确，那么封装短信对象StandartSubmit对象,一个发送目标手机号对应一个短信对象
        for (String mobile : mobileArray) {
            StandardSubmit standardSubmit = new StandardSubmit();
            long id = idWorker.nextId();
            //当前Submit的唯一标识
            standardSubmit.setSequenceId(String.valueOf(id));
            //客户端ID
            standardSubmit.setClientID(Integer.parseInt(smsForm.getClientID()));
            //消息的优先级 0 最低 --- 3 最高
            standardSubmit.setMessagePriority(Short.parseShort(clientMap.get("priority")));
            //客户侧唯一序列号
            standardSubmit.setSrcSequenceId(Long.parseLong(smsForm.getSrcID()));
            //目的手机号
            standardSubmit.setDestMobile(mobile);
            //短信内容
            standardSubmit.setMessageContent(smsForm.getContent());
            //手机接收的状态值  0 成功 1 等待 2 失败
            standardSubmit.setReportState(ReportStateConstants.WAIT);
            //短信发送时间
            standardSubmit.setSendTime(new Date());
            //发送方式 1 HTTP 2 WEB
            standardSubmit.setSource(SourceType.HTTP);

            //9.将封装好的对象发到MQ的队列中，供策略模块使用
            rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND, standardSubmit);
        }

        resultMap.put("code", "0");
        resultMap.put("msg", "接收成功");
        return resultMap;
    }
}
